package com.chenyuxin.ilp.service.user.Impl;

import cn.hutool.core.bean.BeanUtil;
import org.elasticsearch.script.Script;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.chenyuxin.ilp.exception.BaseException;
import com.chenyuxin.ilp.mapper.user.UserHeadMapper;
import com.chenyuxin.ilp.mapper.user.UserMapper;
import com.chenyuxin.ilp.model.constant.NormalConstant;
import com.chenyuxin.ilp.model.constant.UserSuccessConstant;
import com.chenyuxin.ilp.model.entity.user.User;
import com.chenyuxin.ilp.model.entity.user.UserHead;
import com.chenyuxin.ilp.model.enums.exception.ExceptionEnums;
import com.chenyuxin.ilp.model.enums.exception.FileExceptionEnums;
import com.chenyuxin.ilp.model.enums.exception.UserExceptionEnums;
import com.chenyuxin.ilp.model.pojo.Result;
import com.chenyuxin.ilp.model.vo.user.UserHeadVo;
import com.chenyuxin.ilp.service.file.Impl.MinioServiceImpl;
import com.chenyuxin.ilp.service.user.UserHeadService;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.reindex.UpdateByQueryRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserHeadServiceImpl implements UserHeadService {
    @Autowired
    private UserHeadMapper userHeadMapper;
    @Autowired
    private MinioServiceImpl minioService;
    @Autowired
    private UserMapper userMapper;
    @Value("${minio.bucket.head}")
    private String bucket;
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    // 获取用户头像列表
    @Override
    public Result getHeadList(String userId) {
        LambdaQueryWrapper<UserHead> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserHead::getUserId,userId)
                .orderByDesc(UserHead::getCreateTime);
        List<UserHead> userHeads = userHeadMapper.selectList(wrapper);
        List<UserHeadVo> userHeadVos = userHeads.stream().map(userHead -> {
            UserHeadVo userHeadVo = BeanUtil.copyProperties(userHead, UserHeadVo.class);
            return userHeadVo;
        }).collect(Collectors.toList());
        return Result.ok(userHeadVos);
    }
    @Transactional
    @Override
    public Result addHead(MultipartFile headFile, String userId) {
        //1 保存头像基本信息
        UserHead userHead = new UserHead();
        userHead.setUserId(userId);
        userHead.setCreateTime(LocalDateTime.now());
        userHeadMapper.insert(userHead);
        //2 将头像文件保存到minio
        String originalFilename = headFile.getOriginalFilename();
        String extension = originalFilename.substring(originalFilename.lastIndexOf('.'));
        File tempFile = null;
        try{
            tempFile = File.createTempFile("minio", extension);
            //上传的文件拷贝到临时文件
            headFile.transferTo(tempFile);
        }catch (Exception exception){
            throw new BaseException(ExceptionEnums.SYSTEM_ERROR);
        }
        String absolutePath = tempFile.getAbsolutePath();
        String objectName = "/"+userId+"/"+userHead.getId()+extension;
        Boolean upload = minioService.upload(absolutePath, bucket, objectName,extension);
        if(!upload){
            throw new BaseException(FileExceptionEnums.FILE_UPLOAD_ERROR);
        }
        if (tempFile.exists()) {
            tempFile.delete();
        }
        //3 将头像url保存到minio
        String url = NormalConstant.MINIO_IP +bucket+objectName;
        LambdaUpdateWrapper<UserHead> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(UserHead::getId,userHead.getId())
                .set(UserHead::getHeadUrl,url);
        userHeadMapper.update(wrapper);
        UserHeadVo userHeadVo = new UserHeadVo();
        userHeadVo.setHeadUrl(url);
        userHeadVo.setId(userHead.getId());
        return Result.ok(userHeadVo);
    }
    // 修改用户头像
    @Override
    public Result updateHead(Long headId, String userId) {
        // 查询头像url
        LambdaQueryWrapper<UserHead> userHeadWrapper = new LambdaQueryWrapper<>();
        userHeadWrapper.eq(UserHead::getId,headId)
                .eq(UserHead::getUserId,userId);
        UserHead userHead = userHeadMapper.selectOne(userHeadWrapper);
        if(userHead==null){
            throw new BaseException(UserExceptionEnums.HEAD_NOT_EXIST);
        }
        // 更新用户头像url
        LambdaUpdateWrapper<User> userWrapper = new LambdaUpdateWrapper<>();
        userWrapper.eq(User::getId,userId)
                .set(User::getImg,userHead.getHeadUrl());
        userMapper.update(userWrapper);

        // 更新帖子用户头像信息
        UpdateByQueryRequest request = new UpdateByQueryRequest("post");
        // 查询条件：authorId == x
        request.setQuery(QueryBuilders.termQuery("authorId", userId));
        // 修改脚本：将 authorHead 改为新的头像路径
        String scriptCode = "ctx._source.authorImg = '" + userHead.getHeadUrl() + "'";
        request.setScript(new Script(scriptCode));
        // 可选：设置刷写频率、并发度、超时等
        request.setConflicts("proceed"); // 忽略版本冲突
        request.setRefresh(true); // 修改后立即可见

        // 执行更新
        try {
            restHighLevelClient.updateByQuery(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return Result.ok(UserSuccessConstant.UPDATE_HEAD_SUCCESS,null);
    }
}
